#include <stdlib.h>
#include <iostream>
#include <windows.h>
#include <stdio.h>
#include <gl/glut.h>
#include <gl/gl.h>
#include <gl/glu.h>
#include <gl/glaux.h>
#include <malloc.h>
#include <string>
#include <math.h>
#include <fstream>
#include "Planet.h"
#include "Camera.h"
#include "Moon.h"
#include <string.h>
#include "Stars.h"


#define PI 3.1415

GLdouble fieldOfView;
GLdouble zValue;
GLdouble xLightValue;
double degrees;
double solar_time; // keep track of all time
double time_scale_factor; // scale of speed of time passage
double EARTH_DAY = 360.0/365.25; // earth day
Camera sceneCamera;
double aspectRatioX;
double aspectRatioY;
bool blowUp;
int blowUpCounter;

GLUquadricObj *quadratic;


//I added a texture for the sprites.
GLuint texture[12];

bool right;

bool bDModeOn;
bool bEarthGone;
bool bMarsGone;
bool bJupiterGone;
bool bSaturnGone;
bool bNeptuneGone;
bool bUranusGone;
bool bPlutoGone;

//Create a class
//add sphere texturing...


static GLfloat SpecularColor[] = {0.9,0.3,0.0,0.5};
static GLfloat Intensity[] = {0.5};
static GLfloat LightPos[] = {0.0,0.0,-1.0,1.0};
static GLfloat LightPos2[] = {0.0,1.0,0.0,0.0};
static GLfloat AmbLight[] = {0.1,0.1,0.1,1.0};
static GLfloat Attenuation = 0;
static GLfloat Emission[] = {0.0f, 0.0f, 0.0f, 0.7f};

static GLfloat ZeroMat[] = {0.0f, 0.0f, 0.0f, 1.0f};
//An array of planets that will be iterated
//when drawin and updating the planets
static Planet planets[] = 
{
	Planet("Sun"),
	Planet("Mercury"),
	Planet("Venus"),
	Planet("Earth"),
	Planet("Mars"),
	Planet("Jupiter"),
	Planet("Saturn"),
	Planet("Uranus"),
	Planet("Neptune"),
	Planet("Pluto")
};


static Moon moons[] = 
{
	Moon("EarthMoon"), 
	
	Moon("Deimos"), Moon("Phobos"), 
	
	Moon("Callisto"), Moon("Europa"), Moon("Ganymede"), Moon("Io"),
	
	Moon("Dione"), Moon("Enceladus"), Moon("Iapetus"), Moon("Mimas"), 
	Moon("Rhea"), Moon("Tethys"), Moon("Titan"), 
	
	Moon("Ariel"), Moon("Miranda"), Moon("Oberon"),
	Moon("Titania"), Moon("Umbriel"),
	
	Moon("Proteus"), Moon("Triton"),
	
	Moon("Charon")
}; 

static Stars starMap[] =
{Stars()};

int lockOnPlanetNum;

GLfloat transX = 0.0;
GLfloat transY = 0.0;
GLfloat transZ = 0.0;
GLfloat	lookAtX;
GLfloat	lookAtY;
GLfloat	lookAtZ = -1;

void camera (void) 
{
	glLoadIdentity();

	if(sceneCamera.getLockOn())
	{
		sceneCamera.changeFocus(planets[lockOnPlanetNum].transX,planets[lockOnPlanetNum].transY,planets[lockOnPlanetNum].transZ, planets[lockOnPlanetNum].size*10);
	}

	sceneCamera.calculateVectors();
	
	gluLookAt(sceneCamera.translation[0],sceneCamera.translation[1],sceneCamera.translation[2],
		      sceneCamera.lookAtPoint[0],sceneCamera.lookAtPoint[1], sceneCamera.lookAtPoint[2],
			  sceneCamera.up[0], sceneCamera.up[1], sceneCamera.up[2]);
}


void LoadBitMap(const char *imageFile, GLuint &textureID) {

	BYTE *imageData;
	FILE *file;

	imageData = (BYTE*)malloc(256*256*3);

	file = fopen(imageFile, "rb");
	if(file == NULL) {
		std::cout << imageFile << " is empty"  << std::endl;
	}
	else {
		fread(imageData, 128*128*3, 1, file);
		fclose(file);

		glGenTextures(11, &textureID);
		glBindTexture(GL_TEXTURE_2D, textureID);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
		glTexImage2D(GL_TEXTURE_2D, 0, 3, 128, 128, 0, GL_RGB, GL_UNSIGNED_BYTE, imageData);
		
		gluBuild2DMipmaps(GL_TEXTURE_2D, 3, 128, 128, GL_RGB, GL_UNSIGNED_BYTE, imageData);
		free(imageData);
	}
}
/*
// To load a bitmap that has already been converted to a raw file
GLuint LoadBitMap(const char *fileName) {
	int width = 128;
	int height= 128;

	GLuint text;

	BYTE *data;
	FILE *file;
	

	file = fopen(fileName, "rb");
	if(file == NULL) {
		return 0;
	}

	data = (BYTE*)malloc(width*height*3);

	fread(data, width*height*3, 1, file);
	fclose(file);

	glGenTextures(1, &text);
	glBindTexture(GL_TEXTURE_2D, text);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
	//glTexImage2D(GL_TEXTURE_2D, 0, 3, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
	gluBuild2DMipmaps(GL_TEXTURE_2D, 3, width, height, GL_RGB, GL_UNSIGNED_BYTE, data);
	free(data);

	return text;
}
*/
void Initialize ()							
{

	quadratic = gluNewQuadric();
	gluQuadricDrawStyle(quadratic, GLU_FILL);
	//glClearColor(0.0, 0.0, 0.0, 0.0);
	//glShadeModel(GL_SMOOTH);
	//glMaterialfv(GL_FRONT, GL_SPECULAR, MatSpec);
	//glMaterialfv(GL_FRONT, GL_SHININESS, MatShininess);
	//glLightfv(GL_LIGHT0, GL_POSITION, LightPos);
	//glEnable(GL_LIGHTING);
	//glEnable(GL_LIGHT0);
	//glEnable(GL_DEPTH_TEST);


	const char *sunFile = "sunmap.raw";
	const char *mercuryFile = "mercurymap.raw";
	const char *venusFile = "venusmap.raw";
	const char *earthFile = "earthmap1k.raw";
	const char *marsFile = "mars_1k_color.raw";
	const char *jupiterFile = "jupitermap.raw";
	const char *saturnFile = "saturnmap.raw";
	const char *uranusFile = "uranusmap.raw";
	const char *neptuneFile = "neptunemap.raw";
	const char *plutoFile = "plutomap1k.raw";
	const char *moonFile = "moonmap1k.raw";
	const char *ringFile = "texture.raw";

	LoadBitMap(sunFile, texture[0]);
	
	if(texture[0] == 0) {
		std:: cout << "File did not load" << std::endl;
	}

	LoadBitMap(mercuryFile, texture[1]);
	LoadBitMap(venusFile, texture[2]);
	LoadBitMap(earthFile, texture[3]);
	LoadBitMap(marsFile, texture[4]);
	LoadBitMap(jupiterFile, texture[5]);
	LoadBitMap(saturnFile, texture[6]);
	LoadBitMap(uranusFile, texture[7]);
	LoadBitMap(neptuneFile, texture[8]);
	LoadBitMap(plutoFile, texture[9]);
	LoadBitMap(moonFile, texture[10]);
	LoadBitMap(ringFile, texture[11]);
}

void myReshape(int x, int y)
{

	if(y == 0)
		y = 1;

	//This is a rather typical reshaping function, I wrote this from
	//scratch, however, I did read codecolony.de before so it
	//is similar...
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glViewport(0,0,x,y);  //Use the whole window for rendering
	gluPerspective(fieldOfView,(GLdouble)x/(GLdouble)y,0.1,10000.0);
	aspectRatioX = x;
	aspectRatioY = y;
	
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	camera();		
}

//Given a planet this line will create the matrix
//that is used when openGL draws the models
void renderAPlanet(Planet p)
{
	//sets the matrix = to the identity matrix

	//sets the color using planet parameters
	glColor3f(p.colorR,p.colorG,p.colorB);
	//sets the translation, using the planet parameters
	glTranslatef((GLdouble)p.transX, (GLdouble)p.transY , (GLdouble)p.transZ);
	//sets the scale, but these are all uniform spheres
	
	//glRotatef(p.rotateY,0,1,0);
	//glRotatef(p.rotateX,1,0,0);
	//glRotatef(0,0,0,1);
	
	glScalef(1.0,1.0,1.0);
	//draws the sphere, this is a built in call to draw a simple
	//solid sphere
	glutSolidSphere( (GLdouble)p.size , 20.0 , 20.0);
	//pushes the matrix on to the list of matrices for the planets

	// draw polar axis
	glBegin(GL_LINES);
	if(p.orb_tilt == 0.0)
	{
	glVertex3f(0.0,-1.5*p.size,0.0);
	glVertex3f(0.0,1.5*p.size+5,0.0);
	}
	else
	{
	double axisLength = p.size*1.5;
	double axisTilt = (p.orb_tilt)*PI/180.0;

	glVertex3f(2*axisLength*sin(axisTilt),-axisLength,0.0);
	glVertex3f(-2*axisLength*sin(axisTilt),axisLength,0.0);
	}
	glEnd();
}


void myDisplay()
{
	//clears the color buffer, this is something that seems
	//to exist in all openGL display functions
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	//glLoadIdentity();
	//Lighting components, although right now they
	//aren't enabled in MAIN loop

	glLightModelfv(GL_LIGHT_MODEL_AMBIENT, AmbLight);
	glLightfv(GL_LIGHT0, GL_AMBIENT, AmbLight);
	//glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, LightPos2);
	
	glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 360.0f);
	glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, 2);

	glLightfv(GL_LIGHT0, GL_POSITION, LightPos);


//Draw the SUN
glMaterialfv(GL_FRONT, GL_EMISSION, Emission);

glDisable(GL_LIGHTING);
   glPushMatrix();

   glEnable(GL_TEXTURE_2D);
   glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
   glBindTexture(GL_TEXTURE_2D, texture[0]);	
   glEnable(GL_TEXTURE_GEN_S);
   glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
   glEnable(GL_TEXTURE_GEN_T);
   glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
   //glTextImage2D(GL_TEXTURE_2D, 3, 128, 128, GL_RGB, GL_UNSIGNED_BYTE, 
   renderAPlanet(planets[0]);
   glDisable(GL_TEXTURE_2D);
   
   glPopMatrix();

glEnable(GL_LIGHTING);
glMaterialfv(GL_FRONT, GL_EMISSION, ZeroMat);

	//iterates through the array of planets, updates and draw them	

   //Draw the other planets
if(bDModeOn && (lockOnPlanetNum == 3) )
{
	bEarthGone = true;
}
if(bDModeOn && (lockOnPlanetNum == 4) )
{
	bMarsGone = true;
}
if(bDModeOn && (lockOnPlanetNum == 5) )
{
	bJupiterGone = true;
}
if(bDModeOn && (lockOnPlanetNum == 6) )
{
	bSaturnGone = true;
}
if(bDModeOn && (lockOnPlanetNum == 7) )
{
	bNeptuneGone = true;
}
if(bDModeOn && (lockOnPlanetNum == 8) )
{
	bUranusGone = true;
}
if(bDModeOn && (lockOnPlanetNum == 9) )
{
	bPlutoGone = true;
}

if(bDModeOn)
{
	if( (lockOnPlanetNum > 0) && (lockOnPlanetNum < 10) )
	{
	planets[lockOnPlanetNum].destructionMode(bDModeOn);
	}
}


	for(int i = 1; i<10; i++)
	{

		glPushMatrix();


		if(blowUp && blowUpCounter < 200)
		{
			glEnable(GL_TEXTURE_2D);
			glBindTexture(GL_TEXTURE_2D, texture[0]);

			for(int j = 0; j<3000; j++)
			{
			planets[lockOnPlanetNum].ps.updateSingleParticleExplode(j);

				glBegin(GL_QUADS);
					glTexCoord2f(0.0f,0.0f); glVertex3f(planets[lockOnPlanetNum].ps.particles[j].transform[0]+.05,
														planets[lockOnPlanetNum].ps.particles[j].transform[1],
														planets[lockOnPlanetNum].ps.particles[j].transform[2]+.05);


					glTexCoord2f(0.0f,0.0f); glVertex3f(planets[lockOnPlanetNum].ps.particles[j].transform[0]-.05,
														planets[lockOnPlanetNum].ps.particles[j].transform[1],
														planets[lockOnPlanetNum].ps.particles[j].transform[2]+.05);

					glTexCoord2f(0.0f,0.0f); glVertex3f(planets[lockOnPlanetNum].ps.particles[j].transform[0]-.05,
														planets[lockOnPlanetNum].ps.particles[j].transform[1],
														planets[lockOnPlanetNum].ps.particles[j].transform[2]-.05);

					glTexCoord2f(0.0f,0.0f); glVertex3f(planets[lockOnPlanetNum].ps.particles[j].transform[0]+.05,
														planets[lockOnPlanetNum].ps.particles[j].transform[1],
														planets[lockOnPlanetNum].ps.particles[j].transform[2]-.05);
				glEnd();
			}
			glDisable(GL_TEXTURE_2D);
			blowUpCounter++;
		}
		else
		{
			blowUp = false;
			blowUpCounter = 0.0;
		}

		glEnable(GL_TEXTURE_2D);
		glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
		glBindTexture(GL_TEXTURE_2D, texture[i]);	
		glEnable(GL_TEXTURE_GEN_S);
		glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
		glEnable(GL_TEXTURE_GEN_T);
		glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
		
		planets[i].updatePlanet(time_scale_factor);
		renderAPlanet(planets[i]);
		glDisable(GL_TEXTURE_2D);
		
		//Draw Saturn's Rings
		if( (i==6) && !bSaturnGone)
		{

		glEnable(GL_TEXTURE_2D);
			glBindTexture(GL_TEXTURE_2D, texture[6]);
			for(int j =0; j <5000; j++)
			{	
				glBegin(GL_QUADS);
					glTexCoord2f(0.0f,0.0f); glVertex3f(planets[i].ps.particles[j].transform[0],
														planets[i].ps.particles[j].transform[1],
														planets[i].ps.particles[j].transform[2]);


					glTexCoord2f(0.0f,0.0f); glVertex3f(planets[i].ps.particles[j].transform[0]-.5,
														planets[i].ps.particles[j].transform[1],
														planets[i].ps.particles[j].transform[2]+.5);

					glTexCoord2f(0.0f,0.0f); glVertex3f(planets[i].ps.particles[j].transform[0]-.5,
														planets[i].ps.particles[j].transform[1],
														planets[i].ps.particles[j].transform[2]-.5);

					glTexCoord2f(0.0f,0.0f); glVertex3f(planets[i].ps.particles[j].transform[0]+.5,
														planets[i].ps.particles[j].transform[1],
														planets[i].ps.particles[j].transform[2]-.5);
				glEnd();
			
			}
		}
		glDisable(GL_TEXTURE_2D);
		glPopMatrix();
	}

	glColor3f(1.0,1.0,1.0);
//Draw Planet Orbits
glDisable(GL_LIGHTING);
	for(int j = 0; j<10; j++)
	{
	glPushMatrix();
	glPointSize(2.0);
	glBegin(GL_POINTS);
	for(int i =0 ;i <360; i++)
	{
		glVertex3f(planets[j].orbit[i][0], planets[j].orbit[i][1], planets[j].orbit[i][2]);
	}
	glEnd();
	glPopMatrix();
	}
glEnable(GL_LIGHTING);
//Draw the moons

	for(int i = 0; i < 22; i++) {
		glPushMatrix();
		glEnable(GL_TEXTURE_2D);
		glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
		glBindTexture(GL_TEXTURE_2D, texture[10]);
		glEnable(GL_TEXTURE_GEN_S);
		glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
		glEnable(GL_TEXTURE_GEN_T);
		glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);

		if(i == 0 && !bEarthGone) 
		{
			moons[i].updateMoon(time_scale_factor, planets[3]);
			glColor3f(moons[i].colorR, moons[i].colorG, moons[i].colorB);
		glTranslatef((GLdouble)moons[i].transX, (GLdouble)moons[i].transY, (GLdouble)moons[i].transZ);
		glScalef(1.0, 1.0, 1.0);
		//gluSphere(quadratic, (GLdouble)moons[i].size, 32, 32);
		glutSolidSphere((GLdouble)moons[i].size, 32, 32);
		glDisable(GL_TEXTURE_2D);
		glPopMatrix();
		} 
		else if (i == 1 || i == 2 && !bMarsGone)
		{
			moons[i].updateMoon(time_scale_factor, planets[4]);
			glColor3f(moons[i].colorR, moons[i].colorG, moons[i].colorB);
		glTranslatef((GLdouble)moons[i].transX, (GLdouble)moons[i].transY, (GLdouble)moons[i].transZ);
		glScalef(1.0, 1.0, 1.0);
		//gluSphere(quadratic, (GLdouble)moons[i].size, 32, 32);
		glutSolidSphere((GLdouble)moons[i].size, 32, 32);
		glDisable(GL_TEXTURE_2D);
		glPopMatrix();
		} 
		else if (i > 2 && i < 7 && !bJupiterGone) 
		{
			moons[i].updateMoon(time_scale_factor, planets[5]);
			glColor3f(moons[i].colorR, moons[i].colorG, moons[i].colorB);
		glTranslatef((GLdouble)moons[i].transX, (GLdouble)moons[i].transY, (GLdouble)moons[i].transZ);
		glScalef(1.0, 1.0, 1.0);
		//gluSphere(quadratic, (GLdouble)moons[i].size, 32, 32);
		glutSolidSphere((GLdouble)moons[i].size, 32, 32);
		glDisable(GL_TEXTURE_2D);
		glPopMatrix();
		} 
		else if (i > 6 && i < 14 && !bSaturnGone) 
		{
			moons[i].updateMoon(time_scale_factor, planets[6]);
			glColor3f(moons[i].colorR, moons[i].colorG, moons[i].colorB);
		glTranslatef((GLdouble)moons[i].transX, (GLdouble)moons[i].transY, (GLdouble)moons[i].transZ);
		glScalef(1.0, 1.0, 1.0);
		//gluSphere(quadratic, (GLdouble)moons[i].size, 32, 32);
		glutSolidSphere((GLdouble)moons[i].size, 32, 32);
		glDisable(GL_TEXTURE_2D);
		glPopMatrix();
		}
		else if (i > 13 && i < 19 && !bNeptuneGone) 
		{
			moons[i].updateMoon(time_scale_factor, planets[7]);
			glColor3f(moons[i].colorR, moons[i].colorG, moons[i].colorB);
		glTranslatef((GLdouble)moons[i].transX, (GLdouble)moons[i].transY, (GLdouble)moons[i].transZ);
		glScalef(1.0, 1.0, 1.0);
		//gluSphere(quadratic, (GLdouble)moons[i].size, 32, 32);
		glutSolidSphere((GLdouble)moons[i].size, 32, 32);
		glDisable(GL_TEXTURE_2D);
		glPopMatrix();
		} 
		else if (i > 18 && i < 21 && !bUranusGone) 
		{
			moons[i].updateMoon(time_scale_factor, planets[8]);
			glColor3f(moons[i].colorR, moons[i].colorG, moons[i].colorB);
		glTranslatef((GLdouble)moons[i].transX, (GLdouble)moons[i].transY, (GLdouble)moons[i].transZ);
		glScalef(1.0, 1.0, 1.0);
		//gluSphere(quadratic, (GLdouble)moons[i].size, 32, 32);
		glutSolidSphere((GLdouble)moons[i].size, 32, 32);
		glDisable(GL_TEXTURE_2D);
		glPopMatrix();
		} 
		else if( i > 21 && !bPlutoGone)
		{
			moons[i].updateMoon(time_scale_factor, planets[9]);
			glColor3f(moons[i].colorR, moons[i].colorG, moons[i].colorB);
		glTranslatef((GLdouble)moons[i].transX, (GLdouble)moons[i].transY, (GLdouble)moons[i].transZ);
		glScalef(1.0, 1.0, 1.0);
		//gluSphere(quadratic, (GLdouble)moons[i].size, 32, 32);
		glutSolidSphere((GLdouble)moons[i].size, 32, 32);
		glDisable(GL_TEXTURE_2D);
		glPopMatrix();
		}
		
	}
glColor3f(1.0,1.0,1.0);
glDisable(GL_LIGHTING);
			glPushMatrix();
			glEnable(GL_TEXTURE_2D);
			glBindTexture(GL_TEXTURE_2D, texture[0]);
			for(int j =0; j <1000; j++)
			{	
				glBegin(GL_QUADS);
					glTexCoord2f(0.0f,0.0f); glVertex3f(starMap[0].ps.particles[j].transform[0]+5,
														starMap[0].ps.particles[j].transform[1]+5,
														starMap[0].ps.particles[j].transform[2]);
					glTexCoord2f(0.0f,0.0f); glVertex3f(starMap[0].ps.particles[j].transform[0]-5,
														starMap[0].ps.particles[j].transform[1]+5,
														starMap[0].ps.particles[j].transform[2]);
					glTexCoord2f(0.0f,0.0f); glVertex3f(starMap[0].ps.particles[j].transform[0]-5,
														starMap[0].ps.particles[j].transform[1]-5,
														starMap[0].ps.particles[j].transform[2]);
					glTexCoord2f(0.0f,0.0f); glVertex3f(starMap[0].ps.particles[j].transform[0]+5,
														starMap[0].ps.particles[j].transform[1]-5,
														starMap[0].ps.particles[j].transform[2]);
				glEnd();
			
			}
			glDisable(GL_TEXTURE_2D);
			glPopMatrix();

glEnable(GL_LIGHTING);

	// Incremente the time
	solar_time = solar_time + (EARTH_DAY * time_scale_factor);


	glLoadIdentity();
	sceneCamera.changeFocus(planets[lockOnPlanetNum].transX,planets[lockOnPlanetNum].transY,planets[lockOnPlanetNum].transZ, planets[lockOnPlanetNum].size*4);
	camera();
	

	glFlush();
	glutSwapBuffers();			  
}


//The idle function in openGL executes whenever there is nothing else
//going on, meaning user input or something... Here there is some
//code that moved the x-position of the light then redrawing
//it. The light is not enabled right now.
void myIdle()
{
	if(right)
	{
		if(xLightValue > 20)
		{
			right = false;
		}
		xLightValue += .1;
	}
	else
	{
		if(xLightValue < -20)
		{
			right = true;
		}
		xLightValue -=.1;
	}

	myDisplay();
}

//A timer function, this function, which is set in the main function,
//gets called after a set time, and then executes, I don't know what
//this could be used for...
void myTimer(int a)
{
}

//If a key is pressed this functions is called and checks to see
//if the key is mapped to some code, usually the escape key will exit
void myKeyboardFunc(unsigned char key, int a, int b)
{
	bool madeCameraChange = false;
	if(key == 's' || key == 'S')
	{
		lockOnPlanetNum = 0;
		madeCameraChange = true;
	}

	if(key == 'm' || key == 'M')
	{
		lockOnPlanetNum = 1;
		madeCameraChange = true;
	}

	if(key == 'v' || key == 'V')
	{
		lockOnPlanetNum = 2;
		madeCameraChange = true;
	}

	//Move to Earth
	if(key == 'e' || key == 'E')
	{
		lockOnPlanetNum = 3;
		madeCameraChange = true;
	}

	if(key == 'a' || key == 'A')
	{
		lockOnPlanetNum = 4;
		madeCameraChange = true;
	}

	if(key == 'j' || key == 'J')
	{
		lockOnPlanetNum = 5;
		madeCameraChange = true;
	}

	if(key == 't' || key == 'T')
	{
		lockOnPlanetNum = 6;
		madeCameraChange = true;
	}

	if(key == 'u' || key == 'U')
	{
		lockOnPlanetNum = 7;
		madeCameraChange = true;
	}

	if(key == 'n' || key == 'N')
	{
		lockOnPlanetNum = 8;
		madeCameraChange = true;
	}

	if(key == 'p' || key == 'P')
	{
		lockOnPlanetNum = 9;
		madeCameraChange = true;
	}

	if(key == 'z')
	{
		fieldOfView -= .1;
		myReshape(aspectRatioX, aspectRatioY);
	}
	if(key == 'Z')
	{
		fieldOfView -= 1.0;
		myReshape(aspectRatioX, aspectRatioY);
	}

	if(key == 'x')
	{
		fieldOfView += .1;
		myReshape(aspectRatioX, aspectRatioY);
	}
	if(key == 'X')
	{
		fieldOfView += 1.0;
		myReshape(aspectRatioX, aspectRatioY);
	}

	if(key == 'q' || key == 'Q')
	{
		sceneCamera.increaseOffset();
	}

	if(key == 'w' || key == 'W')
	{
		sceneCamera.decreaseOffset();
	}

		if(key == '-')
	{
		if(time_scale_factor > -0.5)
		{
			time_scale_factor -= 0.05; // decrement time
		}
		
	}

	if(key == '=')
	{
		if(time_scale_factor < 10.0)
		{
			time_scale_factor += 0.05 ; // increment time
		}

	}
	if(key == '_')
	{
		if(time_scale_factor > 0.4)
		{
			time_scale_factor -= 0.5; // decrement time
		}
		if(time_scale_factor <= 0.5)
		{
			time_scale_factor = 0.0; // decrement time
		}
		
	}
	if(key == '+')
	{
		if(time_scale_factor < 9.55)
		{
			time_scale_factor += 0.5; // decrement time
		}
		if(time_scale_factor >= 9.55)
		{
			time_scale_factor = 10.0; // decrement time
		}
		
	}

		if(key == '0' || key == ')' )
	{
		time_scale_factor = 0.0; // stop time
		
	}
		if(key == '9' || key == '(' )
	{
		time_scale_factor = 10.0; // stop time
		
	}
		
		if(key == '*' )
	{
		if(!bDModeOn) // destruction mode
			{
				bDModeOn = true;
				blowUp = true;
				blowUpCounter = 0.0;
		}
				
		
	}

	if( key == 'd' || key == 'D')
	{
		lockOnPlanetNum = 9;
		madeCameraChange = true; 
		planets[9].blowUpPlanet();
		blowUp = true;
	}

	if(madeCameraChange)
	{
	sceneCamera.changeFocus(planets[lockOnPlanetNum].transX,planets[lockOnPlanetNum].transY,planets[lockOnPlanetNum].transZ, planets[lockOnPlanetNum].size*50);
	sceneCamera.rotationX =	 45.0;
	sceneCamera.rotationY =  45.0;
	sceneCamera.resetOffset();
	camera();
	}
}

//This is for non-ASCII keys, so things like UP, DOWN, LEFT, and RIGHT
void mySpecialKeys(int a, int b, int c)
{
	
	switch(a)
	{
		//Move Up
		case GLUT_KEY_UP :
			sceneCamera.rotationY -= 1;
			camera();
			break;

		case GLUT_KEY_DOWN :
			sceneCamera.rotationY += 1;
			camera();
			break;

		case GLUT_KEY_RIGHT :
			sceneCamera.rotationX -= 1;
			camera();
			break;
		
		case GLUT_KEY_LEFT :
			sceneCamera.rotationX += 1;
			camera();
			break;
	}


}

int main(int argc, char **argv)
{
	//This is the setup for GL to start
	glutInit(&argc, argv);
	glutInitWindowSize(650,500);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
	glutCreateWindow("Solar System");
	glClearColor(0.0,0.0,0.0,0.0);
	
	//Some global variables being set, probably not the best idea...
	fieldOfView = 70.0;
	xLightValue = 0.0;
	zValue = -4.0;
	degrees = 0;
	right = true;
	solar_time = 0.0;
	time_scale_factor = 0.5;
blowUp = false;
	lockOnPlanetNum = 0;

	// destruction mode
	bDModeOn = false;
	bool bEarthGone = false;
	bool bMarsGone = false;
	bool bJupiterGone = false;
	bool bSaturnGone = false;
	bool bNeptuneGone = false;
	bool bUranusGone = false;
	bool bPlutoGone = false;

	sceneCamera.changeFocus(planets[lockOnPlanetNum].transX,planets[lockOnPlanetNum].transY,planets[lockOnPlanetNum].transZ, planets[lockOnPlanetNum].size*10);
	sceneCamera.rotationX =	 45.0;
	sceneCamera.rotationY =  45.0;

	Initialize();
	starMap[0].setUpStars();
	//Main loop functions
	//sets the callback functions that the main loop
	//will go through
	glutSpecialFunc(mySpecialKeys);
	glutDisplayFunc(myDisplay);
	glutIdleFunc(myIdle);
	glutReshapeFunc(myReshape);

	glutTimerFunc(1000, myTimer, 100);
	glutKeyboardFunc(myKeyboardFunc);


	//This is all for lighting, which is again not enabled
	//It sets up the Specular, ambient and Shininess, using the
	//global settings

	glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, SpecularColor);
	glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, Intensity);
	glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, AmbLight); 
	
	glShadeModel(GL_SMOOTH);

	//you can un comment this to see the lighting
	//right now it doesn't reall show anything
	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);
	
	glEnable(GL_DEPTH_TEST);

	for(int i = 0; i<10; i++)
	{
		planets[i].initializeOrbit();
	}
	planets[6].initializeRings();

	glutMainLoop();
	return 0;
}
